import time
import json
import socket
import uuid
import shlex

import psutil
import requests

from config import settings

class ZiNiaoBrowserTools:
    browser_exe_path = settings.ziniao.exe_path  # 紫鸟的运行路径
    # --run_type=web_driver --socket_port=9999 --run_min_windows=false
    port = 9999
    command = f'{browser_exe_path} --run_type=web_driver --socket_port={port} --run_min_windows=false'
    command_kill_browser = shlex.split('taskkill /F /IM SuperBrowser.exe')

    def __init__(self):
        # self.kill_browser()
        try:
            if 'SuperBrowser.exe' not in [psutil.Process(pid).name() for pid in psutil.pids()]:
                self.start()
        except:
            self.restart()
        ...

    def kill_browser(self):
        if 'SuperBrowser.exe' in [psutil.Process(pid).name() for pid in psutil.pids()]:
            psutil.Popen(self.command_kill_browser)
            time.sleep(1)

    # def __del__(self):
    # log.info(f"关闭紫鸟超级浏览器 pid:{self.process.pid}")
    # if self.is_alive:
    # self.process.kill()

    @property
    def is_alive(self):
        return self.process.is_running()

    def start(self):
        args = shlex.split(self.command)
        self.process = psutil.Popen(args)
        # log.info(f"启动紫鸟超级浏览器 pid:{self.process.pid}")

    def restart(self):
        self.kill_browser()
        self.start()

    def send_socket_msg(self, msg):
        """发送socket消息"""
        # if not is_run_browser():
        #     start_main_browser()
        retry_error_times = 0  # 错误次数，超过退出
        result = ''
        is_success = False
        start_time = time.time()
        while True:
            client = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
            client.settimeout(300)  # 超时时间
            try:
                result = b''
                client.connect(('127.0.0.1', 9999))
                client.send(f'{json.dumps(msg, ensure_ascii=False)}\r\n'.encode('utf-8'))
                buffer_size = int(1024)
                while True:
                    recv = client.recv(buffer_size)
                    if recv:
                        result += recv
                        if recv.endswith(b'\r\n'):
                            # recv_length = len(recv)
                            # if recv.find('\r\n') == recv_length - 2:
                            break
                result = result.decode('utf-8')
                is_success = True
                client.shutdown(socket.SHUT_RDWR)
            except Exception as err:
                # log.error(f'send_msg socket连接失败{err}')
                retry_error_times += 1
            finally:
                client.close()
            if (time.time() - start_time) > 300 * 1.0:
                # log.error(u'send_msg socket连接超时失败')
                return {}, False
            if retry_error_times >= 3:
                # log.error(u'send_msg socket连接超过错误次数')
                return {}, False
            if is_success:
                break
        try:
            return json.loads(result) if is_success else {}, is_success
        except Exception as err:
            ...
            # log.error(u'send_msg Json 解析失败', err)
        return {}, False

    def get_browser_info(self, user_info):
        """查询绑定的店铺信息"""
        data = {
            'userInfo': user_info,
            'action': 'getBrowserList',
            'requestId': str(uuid.uuid4())
        }
        return self.send_socket_msg(data)

    def get_browser_oauth(self, user_info, shop_name, with_ip=None):
        """
        获取 browser_oauth
        """
        result = self.get_browser_info(user_info)

        if result[0]['statusCode'] == 0:
            for browser in result[0]['browserList']:
                if shop_name.lower() in browser['browserName'].lower():
                    if with_ip:
                        return (browser['browserOauth'], browser['browserIp'], browser['browserName'])
                    return browser['browserOauth']
        else:
            raise ModuleNotFoundError

    def start_browser(self, user_info, browserOauth):
        """
        启动指定店铺
        """
        data = {
            'userInfo': user_info,
            'browserOauth': browserOauth,
            'action': 'startBrowser',
            # 'xhrDataPath': get_xhr_data_path(xhr_data_pre_path, browser_oauth),
            'isHeadless': False,
            'requestId': str(uuid.uuid4())
        }

        return self.send_socket_msg(data)

    def stop_browser(self, user_info, browser_oauth):
        """
        关闭店铺
        """
        data = {
            'userInfo': user_info,
            "browserOauth": browser_oauth,
            'action': 'stopBrowser',
            'requestId': str(uuid.uuid4())
        }

        return self.send_socket_msg(data)

    def exit(self,user_info):
        data = {
            'userInfo': user_info,
            'action': 'exit',
            'requestId': str(uuid.uuid4())
        }
        return self.send_socket_msg(data)

    def get_web_socket_debugger_url(self, url='127.0.0.1', port=None):
        """
        获取 webSocketDebuggerUrl
        """
        if not port:
            # log.error('没有传入端口参数')
            return
        # http://127.0.0.1:43559/json/version
        resp = requests.get(f'http://{url}:{port}/json/version')
        return resp.json()['webSocketDebuggerUrl']


